package org.example.Proxy;

import cn.hutool.core.lang.Console;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.Unpooled;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.http.*;

import java.net.InetSocketAddress;

public class NettyReverseProxy {

    private static final String TARGET_HOST = "www.baidu.com"; // 后端服务器地址
    private static final int TARGET_PORT = 80; // 后端服务器端口

    public static void main(String[] args) throws Exception {
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            ServerBootstrap b = new ServerBootstrap();
            b.group(bossGroup, workerGroup)
                    .channel(NioServerSocketChannel.class)
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        public void initChannel(SocketChannel ch) throws Exception {
                            ch.pipeline().addLast(new ReverseProxyHandler());
                        }
                    });

            b.bind(8001).sync().channel().closeFuture().sync();
        } finally {
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }

    private static class ReverseProxyHandler extends ChannelInboundHandlerAdapter {
        @Override
        public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
            Console.log("msg:[{}]",msg);
            if (msg instanceof HttpRequest request) {

                Console.log("request:[{}]",request);
                // 创建发往后端服务器的请求
                FullHttpRequest fullRequest = createFullHttpRequest(request);

                // 连接到后端服务器并发送请求
                ChannelFuture future = ctx.channel().connect(new InetSocketAddress(TARGET_HOST, TARGET_PORT));
                future.addListener(channelFuture -> {
                    Channel backendChannel = ctx.close().channel();
                    // 发送请求到后端服务器
                    backendChannel.writeAndFlush(fullRequest);

                    // 将后端服务器的响应转发给客户端
                    backendChannel.pipeline().addLast(new ChannelInboundHandlerAdapter() {
                        @Override
                        public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
                            if (msg instanceof HttpObject) {
                                ctx.writeAndFlush(msg);
                            }
                        }
                    });
                });
            }
        }

        private FullHttpRequest createFullHttpRequest(HttpRequest request) {
            // 这里简化处理，直接将原始请求转发给后端服务器，实际应用中可能需要进行更复杂的处理，如修改请求头、添加身份验证等。
            FullHttpRequest fullRequest = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, request.method(), request.uri(), Unpooled.wrappedBuffer(new byte[0]));
            fullRequest.headers().set(request.headers());
            return fullRequest;
        }
    }
}